﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using TweetSharp.Twitter.Extensions;
using TweetSharp.Twitter.Fluent;
using TweetSharp.Twitter.Model;

namespace Halfwit
{
    public abstract class TwitterUpdateContext
    {
        public string Prefix { get { return GetPrefix(); } }
        public string Message { get { return GetMessage(); } }

        protected abstract string GetPrefix();
        protected abstract string GetMessage();
        protected abstract ITwitterLeafNode GetUpdateReqest(IFluentTwitter request, string text);

        protected virtual bool IsValid(string text)
        {
            return false;
        }

        public bool IsValidText(string text)
        {
            if (String.IsNullOrEmpty(text.Trim())) return false;

            if (text.Length <= 140) return true;

            return IsValid(text);
        }

        public ITwitterLeafNode GetRequest(IFluentTwitter twitter, string text)
        {
            return GetUpdateReqest(twitter, text);
        }
    }

    public class TwitterReplyContext : TwitterUpdateContext
    {
        public TwitterReplyContext(TwitterStatus status)
        {
            this.Status = status;
        }

        public TwitterStatus Status { get; private set; }

        protected override string GetPrefix()
        {
            return "@" + Status.User.ScreenName + " ";
        }

        protected override string GetMessage()
        {
            return "Replying to @" + Status.User.ScreenName;
        }

        protected override ITwitterLeafNode GetUpdateReqest(IFluentTwitter request, string text)
        {
            return request.Statuses().Update(text).InReplyToStatus(Status);
        }
    }

    public class TwitterReplyAllContext : TwitterUpdateContext
    {
        public TwitterReplyAllContext(TwitterStatus status)
        {
            this.Status = status;
        }

        public TwitterStatus Status { get; private set; }

        protected override string GetPrefix()
        {
            return "@" + Status.User.ScreenName + String.Join(String.Empty, this.Status.TextMentions.Where(n => n != TwitterConnection.User.ScreenName).Select(n => " @" + n).ToArray()) + " ";
        }

        protected override string GetMessage()
        {
            return "Replying to @" + Status.User.ScreenName;
        }

        protected override ITwitterLeafNode GetUpdateReqest(IFluentTwitter request, string text)
        {
            return request.Statuses().Update(text).InReplyToStatus(Status);
        }
    }

    public class TwitterRetweetContext : TwitterUpdateContext
    {
        public TwitterRetweetContext(TwitterStatus status)
        {
            this.Status = status;
        }

        public TwitterStatus Status { get; private set; }

        protected override string GetPrefix()
        {
            return "♺ @" + Status.User.ScreenName + ": ";
        }

        protected override string GetMessage()
        {
            return "Retweeting @" + Status.User.ScreenName;
        }

        protected override ITwitterLeafNode GetUpdateReqest(IFluentTwitter request, string text)
        {
            if (text == System.Web.HttpUtility.HtmlDecode(Prefix + Status.Text))
            {
                // it's an unmodified retweet
                return request.Statuses().Retweet(Status, RetweetMode.Native);
            }
            return request.Statuses().Update(text).InReplyToStatus(Status.Id);

        }

        protected override bool IsValid(string text)
        {
            if (text == Prefix + Status.Text)
            {
                return Status.Text.Length <= 140;
            }
            return false;
        }
    }

    public class TwitterDirectMessageContext : TwitterUpdateContext
    {
        public TwitterDirectMessageContext(TwitterUser user)
        {
            this.User = user;
        }

        public TwitterUser User { get; private set; }

        protected override string GetPrefix()
        {
            return "d " + User.ScreenName + " ";
        }

        protected override string GetMessage()
        {
            return "Sending a direct message to @" + User.ScreenName;
        }

        protected override ITwitterLeafNode GetUpdateReqest(IFluentTwitter request, string text)
        {
            return request.Statuses().Update(text);
            // "This method requires a GET"???
            // return request.DirectMessages().Send(User.Id, text);
        }
    }
}
